<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生能力分管理系统</title>
    <style>
        /* 极简风格 CSS */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }



        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
            line-height: 1.6;
            color: #1f2937;
            background-color: #ffffff;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 16px;
        }

        header {
            padding: 32px 0;
            text-align: center;
            margin-bottom: 16px;
        }

        header h1 {
            font-size: 1.8rem;
            font-weight: 600;
            margin: 0;
            color: #1f2937;
        }

        nav {
            margin-bottom: 16px;
            border-bottom: 1px solid #e5e7eb;
            display: flex;
            justify-content: space-between;
            align-items: center;
            position: sticky;
            top: 0;
            background-color: white;
            z-index: 100;
            padding: 8px 0;
        }

        nav ul {
            list-style: none;
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
        }

        nav ul li {
            margin: 0;
        }

        nav ul li a {
            display: block;
            padding: 10px 16px;
            color: #4b5563;
            text-decoration: none;
            border-bottom: 2px solid transparent;
            transition: all 0.2s ease;
            border-radius: 4px;
        }

        nav ul li a:hover {
            border-bottom: 2px solid #3b82f6;
            color: #3b82f6;
            background-color: #f0f9ff;
            transform: translateY(-1px);
        }

        /* 当前活动的导航链接样式 */
        nav ul li a.active {
            border-bottom: 2px solid #3b82f6;
            color: #3b82f6;
            background-color: #f0f9ff;
        }

        /* 用户信息和注销按钮样式 */
        .user-info {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .user-info span {
            color: #4b5563;
            font-size: 0.9rem;
        }

        .logout-button {
            padding: 6px 12px;
            background-color: #ef4444;
            color: white;
            border: none;
            border-radius: 4px;
            font-size: 14px;
            cursor: pointer;
            transition: background-color 0.2s ease;
        }

        .logout-button:hover {
            background-color: #dc2626;
        }

        main {
            display: flex;
            flex-direction: column;
            gap: 16px;
        }

        section {
            background-color: white;
            padding: 20px;
            border: 1px solid #e5e7eb;
        }

        section h2 {
            color: #1f2937;
            margin-bottom: 16px;
            padding-bottom: 8px;
            border-bottom: 1px solid #e5e7eb;
            font-size: 1.2rem;
            font-weight: 600;
        }

        .search-container {
            margin-bottom: 16px;
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
        }

        .search-container input {
            flex: 1;
            min-width: 250px;
            padding: 8px 12px;
            border: 1px solid #d1d5db;
            border-radius: 4px;
            font-size: 15px;
        }

        .search-container input:focus {
            outline: none;
            border-color: #3b82f6;
        }

        .search-container button {
            padding: 8px 16px;
            background-color: #3b82f6;
            color: white;
            border: none;
            border-radius: 4px;
            font-size: 15px;
            cursor: pointer;
        }

        .result-table {
            overflow-x: auto;
            max-height: 500px;
            overflow-y: auto;
            border: 1px solid #e5e7eb;
            margin-bottom: 16px;
        }

        .result-table table {
            width: 100%;
            border-collapse: collapse;
        }

        .result-table thead {
            position: sticky;
            top: 0;
            background-color: #f9fafb;
            z-index: 10;
        }

        .result-table th,
        .result-table td {
            padding: 8px 12px;
            text-align: left;
            border-bottom: 1px solid #e5e7eb;
            font-size: 0.95rem;
        }

        .result-table th {
            font-weight: 600;
            color: #1f2937;
        }

        .result-table tr:nth-child(even) {
            background-color: #f9fafb;
        }

        /* 分页样式 */
        .pagination {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 6px;
            margin-top: 12px;
            flex-wrap: wrap;
        }

        .pagination button {
            padding: 5px 8px;
            border: 1px solid #d1d5db;
            background-color: white;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        }

        .pagination button:hover:not(:disabled) {
            background-color: #f3f4f6;
        }

        .pagination button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .pagination .page-info {
            margin: 0 8px;
            color: #6b7280;
            font-size: 14px;
        }

        /* 数据统计样式 */
        .data-stats {
            margin-bottom: 8px;
            color: #6b7280;
            font-size: 0.85rem;
        }

        footer {
            text-align: center;
            padding: 16px;
            margin-top: 16px;
            color: #6b7280;
            font-size: 0.85rem;
        }

        .loading {
            text-align: center;
            padding: 16px;
            color: #3b82f6;
        }

        @media (max-width: 768px) {
            .container {
                padding: 8px;
            }

            header h1 {
                font-size: 1.5rem;
            }

            nav ul {
                flex-direction: column;
                align-items: center;
            }

            section {
                padding: 12px;
            }

            .search-container {
                flex-direction: column;
            }

            .search-container input {
                min-width: auto;
            }
        }
    </style>
</head>

<body>
    <div class="container">
        <header>
            <h1>学生能力分管理系统</h1>
        </header>

        <nav>
            <ul>
                {% if role == 'admin' %}
                <li><a href="#rule-edit">计算规则编辑</a></li>
                {% endif %}
                <li><a href="#calculation">成绩计算</a></li>
                <li><a href="#student-query">学生查询</a></li>
                <li><a href="#project-query">项目查询</a></li>
                <li><a href="#score-query">成绩查询</a></li>
                {% if role == 'admin' %}
                <li><a href="{{ url_for('user_management') }}">用户管理</a></li>
                {% endif %}
            </ul>
            {% if username %}
            <div class="user-info">
                <span>欢迎，{{ username }} ({{ role }})</span>
                <a href="/change_password" style="margin-right: 10px; padding: 6px 12px; background-color: #3b82f6; color: white; border: none; border-radius: 4px; font-size: 14px; cursor: pointer; text-decoration: none;">修改密码</a>
                <a href="/logout"><button class="logout-button">注销</button></a>
            </div>
            {% endif %}
        </nav>

        <main>
            {% if role == 'admin' %}
            <section id="rule-edit">
                <h2>计算规则编辑</h2>
                <div class="rule-editor">
                    <p>点击下方按钮编辑计算规则配置：</p>
                    <button id="edit-rules-button"
                        style="padding: 10px 20px; background-color: #3b82f6; color: white; border: none; border-radius: 4px; font-size: 15px; cursor: pointer;">编辑计算规则</button>
                    <div id="rules-info" class="rules-info"
                        style="margin-top: 10px; color: #6b7280; font-size: 0.85rem;">
                        计算规则已保存在系统配置文件中，可随时修改。修改后将立即生效，不需要重启系统。
                    </div>
                </div>
            </section>

            <!-- 规则编辑模态框 -->
            <div id="rules-modal" class="modal"
                style="display: none; position: fixed; z-index: 100; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.2);">
                <div class="modal-content"
                    style="background-color: white; margin: 5% auto; padding: 20px; border: 1px solid #e5e7eb; width: 80%; max-width: 800px; max-height: 90vh; overflow-y: auto;">
                    <div class="modal-header"
                        style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 1px solid #e5e7eb;">
                        <h3>编辑计算规则(JSON)</h3>
                        <span id="close-rules-modal"
                            style="color: #6b7280; font-size: 24px; cursor: pointer;">&times;</span>
                    </div>
                    <div id="rules-editor-content" class="rules-editor-content">
                        <div class="loading" id="rules-loading"
                            style="text-align: center; padding: 16px; color: #3b82f6;">加载规则配置中...</div>
                        <div id="rules-form" style="display: none;">
                            <div style="margin-bottom: 20px;">
                                <p style="margin-bottom: 10px; color: #6b7280; font-size: 0.9rem;">
                                    请直接编辑JSON格式的规则配置。规则配置支持以下几种类型：</p>
                                <ul style="margin-bottom: 10px; color: #6b7280; font-size: 0.9rem; margin-left: 20px;">
                                    <li>"仅计其中最高分" - 一组项目中只计算得分最高的那个</li>
                                    <li>"最高计1分" - 一组项目中最多获得1分</li>
                                    <li>"最多计2分" - 一组项目中最多获得2分</li>
                                    <li>"仅计1项" - 一组项目中只计算其中一项</li>
                                </ul>
                                <p style="margin-bottom: 10px; color: #6b7280; font-size: 0.9rem;">
                                    每种规则类型可以包含多个规则组，每个规则组是一个项目名称数组。例如：</p>
                                <pre
                                    style="background-color: #f3f4f6; padding: 10px; border-radius: 4px; margin-bottom: 10px; font-size: 0.85rem;">"仅计其中最高分": [
  ["计算机基础", "程序设计基础", "数据结构"],
  ["操作系统", "计算机网络"]
]</pre>
                            </div>
                            <textarea id="rules-json"
                                style="width: 100%; height: 400px; padding: 10px; border: 1px solid #e5e7eb; border-radius: 4px; font-family: 'Courier New', monospace; font-size: 14px; resize: vertical;"></textarea>
                            <div style="margin-top: 10px; color: #ef4444; font-size: 0.85rem; display: none;"
                                id="json-error"></div>
                            <div class="modal-actions"
                                style="display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px;">
                                <button id="cancel-rules-edit"
                                    style="padding: 8px 16px; background-color: #6b7280; color: white; border: none; border-radius: 4px; cursor: pointer;">取消</button>
                                <button id="save-rules"
                                    style="padding: 8px 16px; background-color: #3b82f6; color: white; border: none; border-radius: 4px; cursor: pointer;">保存规则</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            {% endif %}

            <section id="calculation">
                <h2>成绩计算</h2>
                <div style="margin-bottom: 20px;">
                    {% if role == 'admin' %}
                    <button id="calculate-button" onclick="calculateScores()"
                        style="padding: 10px 20px; background-color: #ef4444; color: white; border: none; border-radius: 4px; font-size: 15px; cursor: pointer; margin-right: 10px;">
                        计算学生成绩
                    </button>
                    {% endif %}
                    <button id="export-excel-button" onclick="exportExcel()"
                        style="padding: 10px 20px; background-color: #10b981; color: white; border: none; border-radius: 4px; font-size: 15px; cursor: pointer;">
                        导出Excel
                    </button>
                    <div id="calculation-status"
                        style="margin-top: 12px; display: none; padding: 8px 12px; border-radius: 4px;"></div>
                </div>

                <div style="margin-bottom: 20px;">
                    <div class="search-container">
                        <input type="text" id="calculation-search" placeholder="请输入学号或姓名搜索计算结果">
                        <button onclick="searchCalculationResults()">查询</button>
                    </div>
                </div>

                <div class="result-table">
                    <table>
                        <thead id="calculation-header">
                            <tr>
                                <th>学号</th>
                                <th>姓名</th>
                                <th>模块1</th>
                                <th>模块2</th>
                                <th>模块3</th>
                                <th>总分</th>
                                <th>查看详细</th>
                            </tr>
                        </thead>
                        <tbody id="calculation-result"></tbody>
                    </table>
                </div>

                <!-- 详情模态框 -->
                <div id="detail-modal" class="modal"
                    style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.2); z-index: 1000;">
                    <div class="modal-content"
                        style="background-color: white; margin: 10% auto; padding: 20px; border: 1px solid #e5e7eb; width: 80%; max-width: 800px; max-height: 70vh; overflow-y: auto;">
                        <div
                            style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
                            <h3 style="margin: 0;">学生得分详情</h3>
                            <span id="close-modal"
                                style="cursor: pointer; font-size: 24px; color: #6b7280;">&times;</span>
                        </div>
                        <div id="detail-content" style="margin-bottom: 20px;">
                            <!-- 详情内容将在这里动态生成 -->
                        </div>
                        <button id="close-detail-button"
                            style="padding: 8px 16px; background-color: #3b82f6; color: white; border: none; border-radius: 4px; cursor: pointer;">
                            关闭
                        </button>
                    </div>
                </div>
            </section>

            <section id="student-query">
                <h2>学生信息查询</h2>
                <div class="search-container">
                    <input type="text" id="student-search" placeholder="请输入学号、姓名、年级、专业或班级">
                    <button onclick="searchStudents()">查询</button>
                </div>

                <!-- 学生数据导入功能 -->
                {% if role == 'admin' %}
                <div class="import-container"
                    style="margin-bottom: 20px; padding: 15px; background-color: #f9fafb; border: 1px solid #e5e7eb;">
                    <h3 style="margin-bottom: 10px; font-size: 1.1rem; font-weight: 600;">Excel数据导入</h3>
                    <input type="file" id="student-file" accept=".xlsx,.xls" style="margin-bottom: 10px;">
                    <button onclick="importStudentData()"
                        style="padding: 8px 16px; background-color: #10b981; color: white; border: none; border-radius: 4px; cursor: pointer;">导入学生数据</button>
                    <div id="student-import-status" style="margin-top: 10px; display: none;"></div>
                    <p style="margin-top: 10px; font-size: 0.85rem; color: #6b7280;">Excel文件需包含列：学号、姓名、年级、专业、班级</p>
                </div>
                {% endif %}
                <div class="result-table">
                    <table>
                        <thead>
                            <tr>
                                <th>年级</th>
                                <th>专业</th>
                                <th>班级</th>
                                <th>学号</th>
                                <th>姓名</th>
                            </tr>
                        </thead>
                        <tbody id="student-result"></tbody>
                    </table>
                </div>
            </section>

            <section id="project-query">
                <h2>项目信息查询</h2>
                <div class="search-container">
                    <input type="text" id="project-search" placeholder="请输入项目名称、编号、模块、类别或认定单位">
                    <button onclick="searchProjects()">查询</button>
                </div>

                <!-- 项目数据导入功能 -->
                {% if role == 'admin' %}
                <div class="import-container"
                    style="margin-bottom: 20px; padding: 15px; background-color: #f9fafb; border: 1px solid #e5e7eb;">
                    <h3 style="margin-bottom: 10px; font-size: 1.1rem; font-weight: 600;">Excel数据导入</h3>
                    <input type="file" id="project-file" accept=".xlsx,.xls" style="margin-bottom: 10px;">
                    <button onclick="importProjectData()"
                        style="padding: 8px 16px; background-color: #10b981; color: white; border: none; border-radius: 4px; cursor: pointer;">导入项目数据</button>
                    <div id="project-import-status" style="margin-top: 10px; display: none;"></div>
                    <p style="margin-top: 10px; font-size: 0.85rem; color: #6b7280;">
                        Excel文件需包含列：编号、模块名称、标准项目类别、标准项目名称、认定单位、学习分</p>
                </div>
                {% endif %}
                <div class="result-table">
                    <table>
                        <thead>
                            <tr>
                                <th>编号</th>
                                <th>模块名称</th>
                                <th>标准项目类别</th>
                                <th>标准项目名称</th>
                                <th>认定单位</th>
                                <th>学习分</th>
                                <th>备注</th>
                            </tr>
                        </thead>
                        <tbody id="project-result"></tbody>
                    </table>
                </div>
            </section>

            <section id="score-query">
                <h2>成绩信息查询</h2>
                <div class="search-container">
                    <input type="text" id="score-search" placeholder="请输入学号、姓名、项目名称或项目编号">
                    <button onclick="searchScores()">查询</button>
                </div>

                <!-- 成绩数据导入功能 -->
                {% if role == 'admin' %}
                <div class="import-container"
                    style="margin-bottom: 20px; padding: 15px; background-color: #f9fafb; border: 1px solid #e5e7eb;">
                    <h3 style="margin-bottom: 10px; font-size: 1.1rem; font-weight: 600;">Excel数据导入</h3>
                    <input type="file" id="score-file" accept=".xlsx,.xls" style="margin-bottom: 10px;">
                    <button onclick="importScoreData()"
                        style="padding: 8px 16px; background-color: #10b981; color: white; border: none; border-radius: 4px; cursor: pointer;">导入成绩数据</button>
                    <div id="score-import-status" style="margin-top: 10px; display: none;"></div>
                    <p style="margin-top: 10px; font-size: 0.85rem; color: #6b7280;">
                        Excel文件需包含列：学号、编号（项目编号）<br>注意：导入前请确保学生和项目已存在</p>
                </div>
                {% endif %}
                <div class="result-table">
                    <table>
                        <thead>
                            <tr>
                                <th>学号</th>
                                <th>姓名</th>
                                <th>标准项目名称</th>
                                <th>编号</th>
                            </tr>
                        </thead>
                        <tbody id="score-result"></tbody>
                    </table>
                </div>
            </section>
        </main>

        <footer>
            <p>学生能力分管理系统 &copy; 2025</p>
        </footer>
    </div>

    <script>
        // 显示导入状态
        function showImportStatus(elementId, message, isSuccess) {
            const statusElement = document.getElementById(elementId);
            statusElement.textContent = message;
            statusElement.style.color = isSuccess ? '#27ae60' : '#e74c3c';
            statusElement.style.display = 'block';

            // 3秒后隐藏状态消息
            setTimeout(() => {
                statusElement.style.display = 'none';
            }, 3000);
        }

        // 分页配置
        const paginationConfig = {
            pageSize: 20, // 每页显示的记录数
            currentPage: {
                students: 1,
                projects: 1,
                scores: 1,
                calculations: 1
            },
            totalRecords: {
                students: 0,
                projects: 0,
                scores: 0,
                calculations: 0
            },
            allData: {
                students: [],
                projects: [],
                scores: [],
                calculations: []
            }
        };

        // 创建分页控件
        function createPagination(type, page, totalPages, totalRecords) {
            const paginationContainer = document.createElement('div');
            paginationContainer.className = 'pagination';

            // 添加统计信息
            const statsElement = document.createElement('div');
            statsElement.className = 'data-stats';
            statsElement.textContent = `共 ${totalRecords} 条记录，当前第 ${page} 页，共 ${totalPages} 页`;
            paginationContainer.appendChild(statsElement);

            // 上一页按钮
            const prevButton = document.createElement('button');
            prevButton.textContent = '上一页';
            prevButton.disabled = page <= 1;
            prevButton.onclick = () => goToPage(type, page - 1);
            prevButton.style.margin = '0 5px';
            prevButton.style.padding = '5px 15px';
            prevButton.style.border = '1px solid #ccc';
            prevButton.style.backgroundColor = '#fff';
            prevButton.style.color = '#333';
            prevButton.style.cursor = prevButton.disabled ? 'not-allowed' : 'pointer';
            prevButton.style.opacity = prevButton.disabled ? '0.6' : '1';
            paginationContainer.appendChild(prevButton);

            // 页码按钮（简化版，只显示当前页及前后几页）
            const pageInfo = document.createElement('span');
            pageInfo.className = 'page-info';
            pageInfo.textContent = `第 ${page} 页 / 共 ${totalPages} 页`;
            pageInfo.style.margin = '0 10px';
            paginationContainer.appendChild(pageInfo);

            // 下一页按钮
            const nextButton = document.createElement('button');
            nextButton.textContent = '下一页';
            nextButton.disabled = page >= totalPages;
            nextButton.onclick = () => goToPage(type, page + 1);
            nextButton.style.margin = '0 5px';
            nextButton.style.padding = '5px 15px';
            nextButton.style.border = '1px solid #ccc';
            nextButton.style.backgroundColor = '#fff';
            nextButton.style.color = '#333';
            nextButton.style.cursor = nextButton.disabled ? 'not-allowed' : 'pointer';
            nextButton.style.opacity = nextButton.disabled ? '0.6' : '1';
            paginationContainer.appendChild(nextButton);

            // 页码跳转输入框
            const goToPageContainer = document.createElement('span');
            goToPageContainer.className = 'page-info';
            goToPageContainer.innerHTML = `前往<input type="number" min="1" max="${totalPages}" value="${page}" style="width: 60px; margin: 0 5px; text-align: center; border: 1px solid #ccc; padding: 3px;" id="${type}-page-input">页`;
            goToPageContainer.style.marginLeft = '20px';
            paginationContainer.appendChild(goToPageContainer);

            // 添加页码输入框事件
            const pageInput = goToPageContainer.querySelector(`#${type}-page-input`);
            pageInput.addEventListener('keypress', (e) => {
                if (e.key === 'Enter') {
                    let targetPage = parseInt(pageInput.value);
                    if (isNaN(targetPage) || targetPage < 1) targetPage = 1;
                    if (targetPage > totalPages) targetPage = totalPages;
                    goToPage(type, targetPage);
                }
            });

            return paginationContainer;
        }

        // 跳转到指定页
        function goToPage(type, page) {
            paginationConfig.currentPage[type] = page;

            if (type === 'students') {
                displayStudentsWithPagination(paginationConfig.allData.students);
            } else if (type === 'projects') {
                displayProjectsWithPagination(paginationConfig.allData.projects);
            } else if (type === 'scores') {
                displayScoresWithPagination(paginationConfig.allData.scores);
            } else if (type === 'calculations') {
                displayCalculationsWithPagination(paginationConfig.allData.calculations);
            }
        }

        // 学生数据导入功能
        function importStudentData() {
            const fileInput = document.getElementById('student-file');
            const file = fileInput.files[0];

            if (!file) {
                showImportStatus('student-import-status', '请选择一个Excel文件', false);
                return;
            }

            const formData = new FormData();
            formData.append('file', file);

            // 显示加载状态
            const statusElement = document.getElementById('student-import-status');
            statusElement.textContent = '导入中，请稍候...';
            statusElement.style.color = '#666';
            statusElement.style.backgroundColor = '#f5f5f5';
            statusElement.style.border = '1px solid #e0e0e0';
            statusElement.style.padding = '10px';
            statusElement.style.display = 'block';

            // 调用API上传文件
            fetch('/api/import/students', {
                method: 'POST',
                body: formData
            })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        showImportStatus('student-import-status', data.message, true);
                        // 清空文件输入
                        fileInput.value = '';
                        // 刷新学生列表
                        searchStudents();
                    } else {
                        showImportStatus('student-import-status', data.message, false);
                    }
                })
                .catch(error => {
                    showImportStatus('student-import-status', '导入失败：' + error.message, false);
                    console.error('Error importing student data:', error);
                });
        }

        // 项目数据导入功能
        function importProjectData() {
            const fileInput = document.getElementById('project-file');
            const file = fileInput.files[0];

            if (!file) {
                showImportStatus('project-import-status', '请选择一个Excel文件', false);
                return;
            }

            const formData = new FormData();
            formData.append('file', file);

            // 显示加载状态
            const statusElement = document.getElementById('project-import-status');
            statusElement.textContent = '导入中，请稍候...';
            statusElement.style.color = '#666';
            statusElement.style.backgroundColor = '#f5f5f5';
            statusElement.style.border = '1px solid #e0e0e0';
            statusElement.style.padding = '10px';
            statusElement.style.display = 'block';

            // 调用API上传文件
            fetch('/api/import/projects', {
                method: 'POST',
                body: formData
            })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        showImportStatus('project-import-status', data.message, true);
                        // 清空文件输入
                        fileInput.value = '';
                        // 刷新项目列表
                        searchProjects();
                    } else {
                        showImportStatus('project-import-status', data.message, false);
                    }
                })
                .catch(error => {
                    showImportStatus('project-import-status', '导入失败：' + error.message, false);
                    console.error('Error importing project data:', error);
                });
        }

        // 成绩数据导入功能
        function importScoreData() {
            const fileInput = document.getElementById('score-file');
            const file = fileInput.files[0];

            if (!file) {
                showImportStatus('score-import-status', '请选择一个Excel文件', false);
                return;
            }

            // 显示加载状态
            const statusElement = document.getElementById('score-import-status');
            statusElement.textContent = '检查数据完整性，请稍候...';
            statusElement.style.color = '#666';
            statusElement.style.backgroundColor = '#f5f5f5';
            statusElement.style.border = '1px solid #e0e0e0';
            statusElement.style.padding = '10px';
            statusElement.style.display = 'block';

            // 先检查学生和项目表是否有数据
            Promise.all([
                fetch('/api/students?search='),
                fetch('/api/projects?search=')
            ])
                .then(responses => Promise.all(responses.map(res => res.json())))
                .then(([students, projects]) => {
                    // 检查学生和项目表是否为空
                    if (students.length === 0 || projects.length === 0) {
                        let message = '';
                        if (students.length === 0 && projects.length === 0) {
                            message = '导入失败：学生表和项目表均为空！请先导入学生数据和项目数据。';
                        } else if (students.length === 0) {
                            message = '导入失败：学生表为空！请先导入学生数据。';
                        } else {
                            message = '导入失败：项目表为空！请先导入项目数据。';
                        }
                        showImportStatus('score-import-status', message, false);
                        return Promise.reject(new Error(message));
                    }

                    // 学生和项目表都有数据，继续导入成绩数据
                    const formData = new FormData();
                    formData.append('file', file);

                    statusElement.textContent = '导入中，请稍候...';

                    // 调用API上传文件
                    return fetch('/api/import/scores', {
                        method: 'POST',
                        body: formData
                    });
                })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('服务器响应错误: ' + response.status);
                    }
                    return response.json();
                })
                .then(data => {
                    if (data.success) {
                        showImportStatus('score-import-status', data.message, true);
                        // 清空文件输入
                        fileInput.value = '';
                        // 刷新成绩列表
                        searchScores();
                    } else {
                        showImportStatus('score-import-status', data.message, false);
                    }
                })
                .catch(error => {
                    // 避免重复显示错误消息
                    if (error.message && !error.message.includes('导入失败：')) {
                        showImportStatus('score-import-status', '导入失败：' + error.message, false);
                    }
                    console.error('Error during score data import:', error);
                });
        }

        // 页面加载完成后显示所有数据
        document.addEventListener('DOMContentLoaded', function () {
            searchStudents();
            searchProjects();
            searchScores();

            // 初始化时查询一次计算结果
            searchCalculationResults();

            // 为搜索框添加回车事件
            document.getElementById('student-search').addEventListener('keypress', function (e) {
                if (e.key === 'Enter') searchStudents();
            });

            document.getElementById('project-search').addEventListener('keypress', function (e) {
                if (e.key === 'Enter') searchProjects();
            });

            document.getElementById('score-search').addEventListener('keypress', function (e) {
                if (e.key === 'Enter') searchScores();
            });

            document.getElementById('calculation-search').addEventListener('keypress', function (e) {
                if (e.key === 'Enter') searchCalculationResults();
            });
        });

        // 学生查询功能
        function searchStudents() {
            const searchValue = document.getElementById('student-search').value.trim();
            const resultBody = document.getElementById('student-result');

            // 显示加载中
            resultBody.innerHTML = '<tr><td colspan="5" style="text-align: center; padding: 20px; color: #666; border: 1px solid #e0e0e0;">加载中...</td></tr>';

            // 调用API获取数据
            fetch(`/api/students?search=${encodeURIComponent(searchValue)}`)
                .then(response => response.json())
                .then(data => {
                    // 保存所有数据用于分页
                    paginationConfig.allData.students = data;
                    paginationConfig.totalRecords.students = data.length;
                    paginationConfig.currentPage.students = 1; // 重置为第一页

                    displayStudentsWithPagination(data);
                })
                .catch(error => {
                    resultBody.innerHTML = '<tr><td colspan="5" style="text-align: center; padding: 20px; color: red;">数据加载失败</td></tr>';
                    console.error('Error fetching students:', error);
                });
        }

        // 显示学生列表（带分页）
        function displayStudentsWithPagination(studentList) {
            const resultBody = document.getElementById('student-result');
            const currentPage = paginationConfig.currentPage.students;
            const pageSize = paginationConfig.pageSize;
            const totalRecords = studentList.length;
            const totalPages = Math.max(1, Math.ceil(totalRecords / pageSize));

            // 清空表格和分页
            resultBody.innerHTML = '';

            // 找到并移除旧的分页控件
            const oldPagination = resultBody.parentElement.nextElementSibling;
            if (oldPagination && oldPagination.className === 'pagination') {
                oldPagination.remove();
            }

            if (totalRecords === 0) {
                resultBody.innerHTML = '<tr><td colspan="5" style="text-align: center; padding: 20px;">未找到相关学生信息</td></tr>';
                return;
            }

            // 计算当前页的数据范围
            const startIndex = (currentPage - 1) * pageSize;
            const endIndex = Math.min(startIndex + pageSize, totalRecords);
            const currentPageData = studentList.slice(startIndex, endIndex);

            // 显示当前页的数据
            currentPageData.forEach(student => {
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td>${student.grade}</td>
                    <td>${student.major}</td>
                    <td>${student.class_name}</td>
                    <td>${student.student_id}</td>
                    <td>${student.name}</td>
                `;
                resultBody.appendChild(row);
            });

            // 创建并添加分页控件
            const pagination = createPagination('students', currentPage, totalPages, totalRecords);
            resultBody.parentElement.parentNode.appendChild(pagination);
        }



        // 项目查询功能
        function searchProjects() {
            const searchValue = document.getElementById('project-search').value.trim();
            const resultBody = document.getElementById('project-result');

            // 显示加载中
            resultBody.innerHTML = '<tr><td colspan="7" style="text-align: center; padding: 20px; color: #666; border: 1px solid #e0e0e0;">加载中...</td></tr>';

            // 调用API获取数据
            fetch(`/api/projects?search=${encodeURIComponent(searchValue)}`)
                .then(response => response.json())
                .then(data => {
                    // 保存所有数据用于分页
                    paginationConfig.allData.projects = data;
                    paginationConfig.totalRecords.projects = data.length;
                    paginationConfig.currentPage.projects = 1; // 重置为第一页

                    displayProjectsWithPagination(data);
                })
                .catch(error => {
                    resultBody.innerHTML = '<tr><td colspan="7" style="text-align: center; padding: 20px; color: red;">数据加载失败</td></tr>';
                    console.error('Error fetching projects:', error);
                });
        }

        // 显示项目列表（带分页）
        function displayProjectsWithPagination(projectList) {
            const resultBody = document.getElementById('project-result');
            const currentPage = paginationConfig.currentPage.projects;
            const pageSize = paginationConfig.pageSize;
            const totalRecords = projectList.length;
            const totalPages = Math.max(1, Math.ceil(totalRecords / pageSize));

            // 清空表格和分页
            resultBody.innerHTML = '';

            // 找到并移除旧的分页控件
            const oldPagination = resultBody.parentElement.nextElementSibling;
            if (oldPagination && oldPagination.className === 'pagination') {
                oldPagination.remove();
            }

            if (totalRecords === 0) {
                resultBody.innerHTML = '<tr><td colspan="7" style="text-align: center; padding: 20px;">未找到相关项目信息</td></tr>';
                return;
            }

            // 计算当前页的数据范围
            const startIndex = (currentPage - 1) * pageSize;
            const endIndex = Math.min(startIndex + pageSize, totalRecords);
            const currentPageData = projectList.slice(startIndex, endIndex);

            // 显示当前页的数据
            currentPageData.forEach(project => {
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td>${project.id}</td>
                    <td>${project.module}</td>
                    <td>${project.category}</td>
                    <td>${project.name}</td>
                    <td>${project.unit}</td>
                    <td>${project.score}</td>
                    <td>${project.remark || ''}</td>
                `;
                resultBody.appendChild(row);
            });

            // 创建并添加分页控件
            const pagination = createPagination('projects', currentPage, totalPages, totalRecords);
            resultBody.parentElement.parentNode.appendChild(pagination);
        }

        // 原始显示项目列表函数（保留用于兼容性）


        // 成绩查询功能
        function searchScores() {
            const searchValue = document.getElementById('score-search').value.trim();
            const resultBody = document.getElementById('score-result');

            // 显示加载中
            resultBody.innerHTML = '<tr><td colspan="4" style="text-align: center; padding: 20px; color: #666; border: 1px solid #e0e0e0;">加载中...</td></tr>';

            // 调用API获取数据
            fetch(`/api/scores?search=${encodeURIComponent(searchValue)}`)
                .then(response => response.json())
                .then(data => {
                    // 保存所有数据用于分页
                    paginationConfig.allData.scores = data;
                    paginationConfig.totalRecords.scores = data.length;
                    paginationConfig.currentPage.scores = 1; // 重置为第一页

                    displayScoresWithPagination(data);
                })
                .catch(error => {
                    resultBody.innerHTML = '<tr><td colspan="4" style="text-align: center; padding: 20px; color: red;">数据加载失败</td></tr>';
                    console.error('Error fetching scores:', error);
                });
        }

        // 显示成绩列表（带分页）
        function displayScoresWithPagination(scoreList) {
            const resultBody = document.getElementById('score-result');
            const currentPage = paginationConfig.currentPage.scores;
            const pageSize = paginationConfig.pageSize;
            const totalRecords = scoreList.length;
            const totalPages = Math.max(1, Math.ceil(totalRecords / pageSize));

            // 清空表格和分页
            resultBody.innerHTML = '';

            // 找到并移除旧的分页控件
            const oldPagination = resultBody.parentElement.nextElementSibling;
            if (oldPagination && oldPagination.className === 'pagination') {
                oldPagination.remove();
            }

            if (totalRecords === 0) {
                resultBody.innerHTML = '<tr><td colspan="4" style="text-align: center; padding: 20px;">未找到相关成绩信息</td></tr>';
                return;
            }

            // 计算当前页的数据范围
            const startIndex = (currentPage - 1) * pageSize;
            const endIndex = Math.min(startIndex + pageSize, totalRecords);
            const currentPageData = scoreList.slice(startIndex, endIndex);

            // 显示当前页的数据
            currentPageData.forEach(score => {
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td>${score.student_id}</td>
                    <td>${score.student_name}</td>
                    <td>${score.project_name}</td>
                    <td>${score.project_id}</td>
                `;
                resultBody.appendChild(row);
            });

            // 创建并添加分页控件
            const pagination = createPagination('scores', currentPage, totalPages, totalRecords);
            resultBody.parentElement.parentNode.appendChild(pagination);
        }



        // 导出Excel功能
        function exportExcel() {
            const exportButton = document.getElementById('export-excel-button');
            const statusElement = document.getElementById('calculation-status');

            // 显示加载状态
            exportButton.disabled = true;
            exportButton.textContent = '导出中...';
            statusElement.textContent = '正在导出Excel文件，请稍候...';
            statusElement.style.color = '#666';
            statusElement.style.backgroundColor = '#f5f5f5';
            statusElement.style.border = '1px solid #e0e0e0';
            statusElement.style.padding = '10px';
            statusElement.style.display = 'block';

            // 获取当前搜索条件
            const searchValue = document.getElementById('calculation-search').value.trim();

            // 调用API导出Excel
            fetch(`/api/export_excel?search=${encodeURIComponent(searchValue)}`, {
                method: 'GET'
            })
                .then(response => {
                    // 恢复按钮状态
                    exportButton.disabled = false;
                    exportButton.textContent = '导出Excel';

                    if (response.ok) {
                        return response.blob();
                    } else {
                        throw new Error('导出失败：' + response.statusText);
                    }
                })
                .then(blob => {
                    // 创建下载链接
                    const url = window.URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = '学生成绩计算结果_' + new Date().toISOString().slice(0, 10) + '.xlsx';
                    document.body.appendChild(a);
                    a.click();

                    // 清理
                    document.body.removeChild(a);
                    window.URL.revokeObjectURL(url);

                    // 显示成功消息
                    statusElement.textContent = 'Excel文件导出成功！';
                    statusElement.style.color = '#333';
                    statusElement.style.backgroundColor = '#f0f8f0';
                    statusElement.style.border = '1px solid #e0e0e0';

                    // 3秒后隐藏成功消息
                    setTimeout(() => {
                        statusElement.style.display = 'none';
                    }, 3000);
                })
                .catch(error => {
                    // 恢复按钮状态
                    exportButton.disabled = false;
                    exportButton.textContent = '导出Excel';

                    // 显示错误消息
                    statusElement.textContent = error.message;
                    statusElement.style.color = '#333';
                    statusElement.style.backgroundColor = '#fff5f5';
                    statusElement.style.border = '1px solid #e0e0e0';

                    console.error('Error exporting Excel:', error);
                });
        }

        // 成绩计算功能
        function calculateScores() {
            const calculateButton = document.getElementById('calculate-button');
            const statusElement = document.getElementById('calculation-status');

            // 显示加载状态
            calculateButton.disabled = true;
            calculateButton.textContent = '计算中...';
            statusElement.textContent = '正在计算成绩，请稍候...';
            statusElement.style.color = '#666';
            statusElement.style.backgroundColor = '#f5f5f5';
            statusElement.style.border = '1px solid #e0e0e0';
            statusElement.style.padding = '10px';
            statusElement.style.display = 'block';

            // 调用API计算成绩
            fetch('/api/calculate_scores', {
                method: 'GET'
            })
                .then(response => response.json())
                .then(data => {
                    // 恢复按钮状态
                    calculateButton.disabled = false;
                    calculateButton.textContent = '计算学生成绩';

                    if (data.success) {
                        // 显示成功消息
                        statusElement.textContent = data.message;
                        statusElement.style.color = '#333';
                        statusElement.style.backgroundColor = '#f0f8f0';
                        statusElement.style.border = '1px solid #e0e0e0';

                        // 刷新计算结果
                        searchCalculationResults();

                        // 3秒后隐藏成功消息
                        setTimeout(() => {
                            statusElement.style.display = 'none';
                        }, 3000);
                    } else {
                        // 显示失败消息
                        statusElement.textContent = '计算失败：' + data.message;
                        statusElement.style.color = '#333';
                        statusElement.style.backgroundColor = '#fff5f5';
                        statusElement.style.border = '1px solid #e0e0e0';
                    }
                })
                .catch(error => {
                    // 恢复按钮状态
                    calculateButton.disabled = false;
                    calculateButton.textContent = '计算学生成绩';

                    // 显示错误消息
                    statusElement.textContent = '计算失败：' + error.message;
                    statusElement.style.color = '#e74c3c';
                    statusElement.style.backgroundColor = '#ffebee';

                    console.error('Error calculating scores:', error);
                });
        }

        // 查询计算结果
        function searchCalculationResults() {
            const searchValue = document.getElementById('calculation-search').value.trim();
            const resultBody = document.getElementById('calculation-result');

            // 显示加载中
            resultBody.innerHTML = '<tr><td colspan="5" class="loading">加载中...</td></tr>';

            // 调用API获取计算结果
            fetch(`/api/calculation_results?search=${encodeURIComponent(searchValue)}`)
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        // 保存所有数据用于分页
                        let results = data.results || [];

                        // 根据搜索条件过滤结果
                        if (searchValue) {
                            results = results.filter(result =>
                                result.student_id.toLowerCase().includes(searchValue.toLowerCase()) ||
                                result.name.toLowerCase().includes(searchValue.toLowerCase())
                            );
                        }

                        paginationConfig.allData.calculations = results;
                        paginationConfig.totalRecords.calculations = results.length;
                        paginationConfig.currentPage.calculations = 1; // 重置为第一页

                        displayCalculationsWithPagination(results);
                    } else {
                        resultBody.innerHTML = '<tr><td colspan="5" style="text-align: center; padding: 20px; color: red;">数据加载失败：' + data.message + '</td></tr>';
                    }
                })
                .catch(error => {
                    resultBody.innerHTML = '<tr><td colspan="5" style="text-align: center; padding: 20px; color: red;">数据加载失败</td></tr>';
                    console.error('Error fetching calculation results:', error);
                });
        }

        // 显示计算结果列表（带分页）
        function displayCalculationsWithPagination(resultList) {
            // 处理空状态显示的列数
            if (resultList.length === 0) {
                const resultBody = document.getElementById('calculation-result');
                resultBody.innerHTML = '<tr><td colspan="' + (Object.keys(paginationConfig.modules || {}).length + 4) + '" style="text-align: center; padding: 20px;">暂无计算结果</td></tr>';
                return;
            }

            // 其余代码保持不变
            const resultBody = document.getElementById('calculation-result');
            const resultHeader = document.getElementById('calculation-header');
            const currentPage = paginationConfig.currentPage.calculations;
            const pageSize = paginationConfig.pageSize;
            const totalRecords = resultList.length;

            // 清空表格和分页
            resultBody.innerHTML = '';

            // 找到并移除旧的分页控件
            const oldPagination = resultBody.parentElement.nextElementSibling;
            if (oldPagination && oldPagination.className === 'pagination') {
                oldPagination.remove();
            }

            // 实现类似pandas的groupby和pivot功能
            // 1. 按学号、姓名、模块名称分组并求和
            const groupedData = {};
            const allModules = new Set();

            // 先处理所有数据进行分组
            resultList.forEach(result => {
                const key = `${result.student_id}_${result.name}`;
                if (!groupedData[key]) {
                    groupedData[key] = {
                        student_id: result.student_id,
                        name: result.name,
                        modules: {},
                        createdAt: result.created_at
                    };
                }

                // 如果该模块已有分数，则累加
                if (groupedData[key].modules[result.module_name]) {
                    groupedData[key].modules[result.module_name] += parseFloat(result.score);
                } else {
                    groupedData[key].modules[result.module_name] = parseFloat(result.score);
                }

                // 记录所有模块名称
                allModules.add(result.module_name);
            });

            // 转换为数组格式
            const students = Object.values(groupedData);
            const sortedModules = Array.from(allModules).sort();
            const totalPages = Math.max(1, Math.ceil(students.length / pageSize));

            // 2. 动态生成表头
            resultHeader.innerHTML = '';
            const headerRow = document.createElement('tr');
            headerRow.innerHTML = '<th>学号</th><th>姓名</th>';

            // 添加模块列
            sortedModules.forEach(module => {
                const th = document.createElement('th');
                th.textContent = module;
                headerRow.appendChild(th);
            });

            // 添加总分列
            const totalTh = document.createElement('th');
            totalTh.textContent = '总分';
            totalTh.className = 'font-bold';
            headerRow.appendChild(totalTh);

            // 添加查看详细列
            const detailTh = document.createElement('th');
            detailTh.textContent = '查看详细';
            headerRow.appendChild(detailTh);

            resultHeader.appendChild(headerRow);

            // 计算当前页的数据范围
            const startIndex = (currentPage - 1) * pageSize;
            const endIndex = Math.min(startIndex + pageSize, students.length);
            const currentPageData = students.slice(startIndex, endIndex);

            // 3. 显示当前页的数据（透视表格式）
            currentPageData.forEach(student => {
                const row = document.createElement('tr');
                let rowHtml = `<td>${student.student_id}</td><td>${student.name}</td>`;
                let totalScore = 0;

                // 为每个模块添加分数
                sortedModules.forEach(module => {
                    const score = student.modules[module] || 0;
                    totalScore += score;
                    rowHtml += `<td>${score.toFixed(2)}</td>`;
                });

                // 添加总分
                rowHtml += `<td class="font-bold">${totalScore.toFixed(2)}</td>`;

                // 添加详情按钮
                rowHtml += `<td><button onclick="showStudentDetail('${student.student_id}')" 
                    style="padding: 5px 15px; background-color: #f5f5f5; color: #333; border: 1px solid #ccc; cursor: pointer;">
                    详情
                </button></td>`;

                row.innerHTML = rowHtml;
                resultBody.appendChild(row);
            });

            // 创建并添加分页控件
            const pagination = createPagination('calculations', currentPage, totalPages, students.length);
            resultBody.parentElement.parentNode.appendChild(pagination);
        }
        // 显示学生详细得分来源
        function showStudentDetail(studentId) {
            const modal = document.getElementById('detail-modal');
            const detailContent = document.getElementById('detail-content');

            // 显示加载状态
            detailContent.innerHTML = '<div style="text-align: center; padding: 20px;">加载中...</div>';
            modal.style.display = 'block';

            // 调用API获取学生详细得分来源
            fetch(`/api/student_detail?student_id=${encodeURIComponent(studentId)}`)
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        const student = data.student;
                        const scores = data.scores;

                        // 格式化详情内容
                        let html = `
                            <div style="margin-bottom: 20px;">
                                <h4>学生信息</h4>
                                <p>学号：${student.student_id}</p>
                                <p>姓名：${student.name}</p>
                                <p>年级：${student.grade}</p>
                                <p>专业：${student.major}</p>
                                <p>班级：${student.class_name}</p>
                            </div>
                            
                            <div>
                                <h4>详细得分来源</h4>
                                <table style="width: 100%; border-collapse: collapse;">
                                    <thead>
                                        <tr style="background-color: #f2f2f2;">
                                            <th style="padding: 8px; text-align: left; border: 1px solid #ddd;">项目编号</th>
                                            <th style="padding: 8px; text-align: left; border: 1px solid #ddd;">项目名称</th>
                                            <th style="padding: 8px; text-align: left; border: 1px solid #ddd;">模块</th>
                                            <th style="padding: 8px; text-align: left; border: 1px solid #ddd;">类别</th>
                                            <th style="padding: 8px; text-align: left; border: 1px solid #ddd;">分数</th>
                                            <th style="padding: 8px; text-align: left; border: 1px solid #ddd;">备注</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                        `;

                        if (scores.length === 0) {
                            html += `<tr><td colspan="6" style="padding: 20px; text-align: center; border: 1px solid #ddd;">暂无得分记录</td></tr>`;
                        } else {
                            scores.forEach(score => {
                                html += `
                                    <tr>
                                        <td style="padding: 8px; border: 1px solid #ddd;">${score.project_id}</td>
                                        <td style="padding: 8px; border: 1px solid #ddd;">${score.project_name}</td>
                                        <td style="padding: 8px; border: 1px solid #ddd;">${score.module}</td>
                                        <td style="padding: 8px; border: 1px solid #ddd;">${score.category}</td>
                                        <td style="padding: 8px; border: 1px solid #ddd;">${score.score}</td>
                                        <td style="padding: 8px; border: 1px solid #ddd;">${score.remark || '-'}</td>
                                    </tr>
                                `;
                            });
                        }

                        html += `
                                    </tbody>
                                </table>
                            </div>
                        `;

                        detailContent.innerHTML = html;
                    } else {
                        detailContent.innerHTML = `<div style="color: red; padding: 20px;">获取详情失败：${data.message}</div>`;
                    }
                })
                .catch(error => {
                    detailContent.innerHTML = '<div style="color: red; padding: 20px;">获取详情失败</div>';
                    console.error('Error fetching student detail:', error);
                });
        }

        // 关闭模态框
        document.getElementById('close-modal').addEventListener('click', function () {
            document.getElementById('detail-modal').style.display = 'none';
        });

        document.getElementById('close-detail-button').addEventListener('click', function () {
            document.getElementById('detail-modal').style.display = 'none';
        });

        // 点击模态框外部关闭
        window.addEventListener('click', function (event) {
            const modal = document.getElementById('detail-modal');
            if (event.target === modal) {
                modal.style.display = 'none';
            }
        });

        // 计算规则编辑功能
        document.addEventListener('DOMContentLoaded', function () {
            // 规则类型映射
            const ruleTypeMap = {
                'highest-score': '仅计其中最高分',
                'max-1-point': '最高计1分',
                'max-2-points': '最多计2分',
                'only-one-item': '仅计1项'
            };

            // 打开规则编辑模态框
            document.getElementById('edit-rules-button').addEventListener('click', function () {
                const modal = document.getElementById('rules-modal');
                modal.style.display = 'block';
                loadRules();
            });

            // 关闭规则编辑模态框
            document.getElementById('close-rules-modal').addEventListener('click', function () {
                document.getElementById('rules-modal').style.display = 'none';
            });

            // 取消规则编辑
            document.getElementById('cancel-rules-edit').addEventListener('click', function () {
                document.getElementById('rules-modal').style.display = 'none';
            });

            // 点击模态框外部关闭
            window.addEventListener('click', function (event) {
                const modal = document.getElementById('rules-modal');
                if (event.target === modal) {
                    modal.style.display = 'none';
                }
            });

            // 项目名称到编号的映射
            let projectNameMap = {};

            // 预加载项目数据，用于名称到编号的映射
            function loadProjectData() {
                return fetch('/api/projects')
                    .then(response => response.json())
                    .then(projects => {
                        // 构建项目名称到编号的映射
                        projectNameMap = {};
                        projects.forEach(project => {
                            projectNameMap[project.name] = project.id;
                        });
                        return projectNameMap;
                    })
                    .catch(error => {
                        console.error('加载项目数据失败:', error);
                        return {};
                    });
            }

            // 将规则中的项目名称转换为项目编号
            function convertNamesToIds(rules) {
                const convertedRules = {};
                for (const ruleType in rules) {
                    convertedRules[ruleType] = [];
                    rules[ruleType].forEach(group => {
                        const convertedGroup = group.map(projectName => {
                            // 如果名称在映射中存在，返回对应的编号，否则保持原样
                            return projectNameMap[projectName] || projectName;
                        });
                        convertedRules[ruleType].push(convertedGroup);
                    });
                }
                return convertedRules;
            }

            // 将规则中的项目编号转换为项目名称
            function convertIdsToNames(rules) {
                const convertedRules = {};
                const idToNameMap = {};

                // 创建编号到名称的反向映射
                for (const name in projectNameMap) {
                    idToNameMap[projectNameMap[name]] = name;
                }

                for (const ruleType in rules) {
                    convertedRules[ruleType] = [];
                    rules[ruleType].forEach(group => {
                        const convertedGroup = group.map(projectId => {
                            // 如果编号在映射中存在，返回对应的名称，否则保持原样
                            return idToNameMap[projectId] || projectId;
                        });
                        convertedRules[ruleType].push(convertedGroup);
                    });
                }
                return convertedRules;
            }

            // 加载规则配置
            function loadRules() {
                const loading = document.getElementById('rules-loading');
                const rulesForm = document.getElementById('rules-form');
                const rulesJsonTextarea = document.getElementById('rules-json');
                const jsonError = document.getElementById('json-error');

                loading.style.display = 'block';
                rulesForm.style.display = 'none';
                jsonError.style.display = 'none';

                // 先加载项目数据
                loadProjectData()
                    .then(() => {
                        // 然后加载规则
                        return fetch('/api/get_rules');
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.success) {
                            // 将规则中的项目编号转换为项目名称后显示
                            const rulesWithNames = convertIdsToNames(data.rules);
                            rulesJsonTextarea.value = JSON.stringify(rulesWithNames, null, 2);
                            loading.style.display = 'none';
                            rulesForm.style.display = 'block';
                        } else {
                            alert('加载规则失败：' + data.message);
                            document.getElementById('rules-modal').style.display = 'none';
                        }
                    })
                    .catch(error => {
                        console.error('加载规则失败:', error);
                        alert('加载规则失败，请稍后重试');
                        document.getElementById('rules-modal').style.display = 'none';
                    });
            }

            // 验证JSON格式
            function validateJSON(jsonString) {
                try {
                    const parsed = JSON.parse(jsonString);
                    // 检查是否为对象
                    if (typeof parsed !== 'object' || parsed === null) {
                        return { valid: false, error: 'JSON必须是一个对象' };
                    }

                    // 检查必要的规则类型是否存在
                    const requiredRuleTypes = ['仅计其中最高分', '最高计1分', '最多计2分', '仅计1项'];
                    requiredRuleTypes.forEach(type => {
                        if (!(type in parsed)) {
                            parsed[type] = [];
                        }
                    });

                    // 检查每个规则类型是否为数组
                    for (const key in parsed) {
                        if (!Array.isArray(parsed[key])) {
                            return { valid: false, error: `规则类型 "${key}" 必须是一个数组` };
                        }
                    }

                    return { valid: true, data: parsed };
                } catch (e) {
                    return { valid: false, error: `JSON格式错误：${e.message}` };
                }
            }

            // 保存规则配置
            function saveRules() {
                const rulesJsonTextarea = document.getElementById('rules-json');
                const jsonError = document.getElementById('json-error');
                const jsonString = rulesJsonTextarea.value.trim();

                // 隐藏之前的错误提示
                jsonError.style.display = 'none';

                // 验证JSON格式
                const validationResult = validateJSON(jsonString);
                if (!validationResult.valid) {
                    jsonError.textContent = validationResult.error;
                    jsonError.style.display = 'block';
                    return;
                }

                // 确保项目数据已加载
                if (Object.keys(projectNameMap).length === 0) {
                    loadProjectData()
                        .then(() => {
                            // 将规则中的项目名称转换为项目编号后保存
                            const rulesWithIds = convertNamesToIds(validationResult.data);
                            saveRulesToServer(rulesWithIds);
                        })
                        .catch(error => {
                            console.error('保存规则失败:', error);
                            alert('保存规则失败，请稍后重试');
                        });
                } else {
                    // 将规则中的项目名称转换为项目编号后保存
                    const rulesWithIds = convertNamesToIds(validationResult.data);
                    saveRulesToServer(rulesWithIds);
                }
            }

            // 保存规则到服务器
            function saveRulesToServer(rules) {
                fetch('/api/update_rules', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ rules: rules })
                })
                    .then(response => response.json())
                    .then(data => {
                        if (data.success) {
                            alert('规则保存成功！');
                            document.getElementById('rules-modal').style.display = 'none';
                        } else {
                            alert('规则保存失败：' + data.message);
                        }
                    })
                    .catch(error => {
                        console.error('保存规则失败:', error);
                        alert('保存规则失败，请稍后重试');
                    });
            }

            // 为保存按钮添加事件监听
            document.getElementById('save-rules').addEventListener('click', saveRules);

            // 为JSON编辑器添加格式化功能
            document.getElementById('rules-json').addEventListener('focusout', function () {
                try {
                    const parsed = JSON.parse(this.value.trim());
                    this.value = JSON.stringify(parsed, null, 2);
                } catch (e) {
                    // 不是有效的JSON，不做处理
                }
            });


        });
    </script>
    <!-- 回到顶部按钮 -->
    
    <!-- 导航栏滚动联动效果 -->
    <script>
        // 页面滚动时更新导航栏活动状态
        window.addEventListener('scroll', updateActiveNavLink);
        // 初始加载时也执行一次
        document.addEventListener('DOMContentLoaded', updateActiveNavLink);
        
        function updateActiveNavLink() {
            // 获取所有导航链接
            const navLinks = document.querySelectorAll('nav ul li a');
            
            // 获取所有页面部分
            const sections = [];
            navLinks.forEach(link => {
                // 对于锚点链接
                if (link.getAttribute('href').startsWith('#')) {
                    const sectionId = link.getAttribute('href').substring(1);
                    const section = document.getElementById(sectionId);
                    if (section) {
                        sections.push({ id: sectionId, element: section });
                    }
                }
            });
            
            // 找到当前可见的部分
            let currentSectionId = null;
            let minDistance = Infinity;
            
            sections.forEach(section => {
                const sectionTop = section.element.offsetTop;
                const sectionHeight = section.element.offsetHeight;
                const scrollY = window.scrollY;
                
                // 计算当前滚动位置与各部分顶部的距离
                const distance = Math.abs(scrollY - sectionTop);
                
                // 如果当前滚动位置在部分内部或距离顶部较近
                if ((scrollY >= sectionTop - 100 && scrollY < sectionTop + sectionHeight - 100) || 
                    (distance < minDistance && sections.length === 1)) {
                    minDistance = distance;
                    currentSectionId = section.id;
                }
            });
            
            // 更新导航链接的活动状态
            navLinks.forEach(link => {
                const href = link.getAttribute('href');
                
                // 处理锚点链接
                if (href.startsWith('#')) {
                    const sectionId = href.substring(1);
                    if (sectionId === currentSectionId) {
                        link.classList.add('active');
                    } else {
                        link.classList.remove('active');
                    }
                } else {
                    // 对于外部链接（如用户管理），保持原有逻辑
                    link.classList.remove('active');
                }
            });
        }
    </script>

</body>

</html>